package com.jtny.nytb.config.measurementunit.service.Impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.jtny.component.core.util.PageUtils;
import com.jtny.component.core.util.QueryWrapperUtils;
import com.jtny.component.dto.CurrentUserDTO;
import com.jtny.component.entity.LocalHolder;
import com.jtny.component.entity.PageData;
import com.jtny.component.enums.GenericStatusEnum;
import com.jtny.component.exception.ServiceException;
import com.jtny.component.util.BeanUtils;
import com.jtny.component.util.CurrentUserUtils;
import com.jtny.nytb.config.errorcode.MeasurementUnitErrorCodeEnum;
import com.jtny.nytb.config.measurementtype.dto.MeasurementTypeDTO;
import com.jtny.nytb.config.measurementtype.service.MeasurementTypeService;
import com.jtny.nytb.config.measurementunit.dao.MeasurementUnitDAO;
import com.jtny.nytb.config.measurementunit.domain.MeasurementUnitDO;
import com.jtny.nytb.config.measurementunit.dto.MeasurementUnitDTO;
import com.jtny.nytb.config.measurementunit.dto.MeasurementUnitPageQueryDTO;
import com.jtny.nytb.config.measurementunit.dto.RepeatMeasurementUnitDTO;
import com.jtny.nytb.config.measurementunit.service.MeasurementUnitService;
import com.jtny.nytb.config.measurementunit.vo.MeasurementUnitPageQueryParamVO;
import com.jtny.nytb.config.measurementunit.vo.MeasurementUnitVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 计量单位Service实现类，具体实现MeasurementUnitService定义的接口
 *
 * @author 智慧能源中心 - lyq
 * @package com.jtny.nytb.config.measurementUnit.service.impl
 * @fileName MeasurementUnitServiceImpl.java
 * @createTime 2023年9月01日 10:08
 * @Copyright© 2023 jtny
 * 江投能源技术研究院 版权所有
 */
@Service
@Slf4j
public class MeasurementUnitServiceImpl implements MeasurementUnitService {

    @Resource
    private MeasurementUnitDAO measurementUnitDAO;
    @Resource
    private MeasurementTypeService measurementTypeService;

    @Override
    public MeasurementUnitDTO save(MeasurementUnitDTO measurementUnitDTO) throws ServiceException {
        // 将DTO对象的属性复制给DO对象
        MeasurementUnitDO measurementUnitDO = BeanUtils.copyToObject(measurementUnitDTO, MeasurementUnitDO.class);
        // 保存操作
        measurementUnitDAO.insert(measurementUnitDO);
        // 将id设置给DTO对象
        measurementUnitDTO.setId(measurementUnitDO.getId());

        return measurementUnitDTO;
    }

    @Override
    public void update(MeasurementUnitDTO measurementUnitDTO) throws ServiceException {
        // 将DTO对象的属性复制给DO对象
        MeasurementUnitDO measurementUnitDO = BeanUtils.copyToObject(measurementUnitDTO, MeasurementUnitDO.class);
        // 修改操作
        measurementUnitDAO.updateById(measurementUnitDO);
    }

    @Override
    public MeasurementUnitDTO getById(Long id) {
        // 通过主键id查询DO对象
        MeasurementUnitDO measurementUnitDO = measurementUnitDAO.selectById(id);

        return BeanUtils.copyToObject(measurementUnitDO, MeasurementUnitDTO.class);
    }

    @Override
    public PageData<MeasurementUnitVO> queryByPage(MeasurementUnitPageQueryParamVO measurementUnitPageQueryParamVO) throws ServiceException {
        //分页查询计量单位信息
        MeasurementUnitPageQueryDTO measurementUnitPageQueryDTO = BeanUtils.copyToObject(measurementUnitPageQueryParamVO, MeasurementUnitPageQueryDTO.class);
        PageData<MeasurementUnitDTO> pageDataForDTO = this.queryPage(measurementUnitPageQueryDTO);
        if(pageDataForDTO == null || CollUtil.isEmpty(pageDataForDTO.getData())){
            return new PageData<>();
        }
        //获取分页查询的数据
        Collection<MeasurementUnitDTO> measurementTypeDTOS = pageDataForDTO.getData();
        //新建返回对线列表
        ArrayList<MeasurementUnitVO> measurementTypeVOList = new ArrayList<>(measurementTypeDTOS.size());
        //返回对象DTO批量转化为VO
        measurementTypeDTOS.forEach(
                measurementUnitDTO ->{
                    MeasurementUnitVO measurementTypeVO = BeanUtils.copyToObject(measurementUnitDTO, MeasurementUnitVO.class);
                    //查询数据库根据计量单位分类id 查出计量单位名称 设置到返回值
                    MeasurementTypeDTO measurementTypeDTO = measurementTypeService.getById(measurementTypeVO.getTypeId());
                    measurementTypeVO.setMeasurementType(measurementTypeDTO.getName());
                    //加入返回列表
                    measurementTypeVOList.add(measurementTypeVO);
                }
        );
        PageData<MeasurementUnitVO> pageDataForVO = pageDataForDTO.transformExcludeData(MeasurementUnitVO.class);
        pageDataForVO.setData(measurementTypeVOList);
        return pageDataForVO;
    }
    @Override
    public PageData<MeasurementUnitDTO> queryPage(@Valid MeasurementUnitPageQueryDTO measurementUnitPageQueryDTO) {
        // 封装查询条件QueryWrapper对象
        QueryWrapper<MeasurementUnitDO> queryWrapper = QueryWrapperUtils.getQueryWrapper(measurementUnitPageQueryDTO);
        queryWrapper.orderByDesc("id");
        if(measurementUnitPageQueryDTO.getTypeId() != null){
            queryWrapper.eq("type_id", measurementUnitPageQueryDTO.getTypeId());
        }
        // 分页查询数据字典信息
        Page<MeasurementUnitDO> page = Page.of(measurementUnitPageQueryDTO.getPageNo(), measurementUnitPageQueryDTO.getPageSize());
        PageData<MeasurementUnitDO> pageDataForDO = PageUtils.getPageData(measurementUnitDAO.selectPage(page, queryWrapper), measurementUnitPageQueryDTO);

        return pageDataForDO.transformData(MeasurementUnitDTO.class);
    }

    @Override
    public List<MeasurementUnitDTO> queryMeasurementUnitByName(RepeatMeasurementUnitDTO repeatMeasurementUnitDTO) {
        //封装查询条件QueryWrapper对象
        QueryWrapper<MeasurementUnitDO> wrapper = new QueryWrapper<>();
        //设置查询条件
        wrapper.eq("name", repeatMeasurementUnitDTO.getMeasurementUnitDTO().getName());
        wrapper.ne("status",9);
        //如果是更新 则去重
        if(repeatMeasurementUnitDTO.getIsUpdate()){
            wrapper.ne("id", repeatMeasurementUnitDTO.getMeasurementUnitDTO().getId());
        }
        List<MeasurementUnitDO> measurementUnitDOS = measurementUnitDAO.selectList(wrapper);
        if(measurementUnitDOS != null && measurementUnitDOS.size() > 0){
            return BeanUtils.copyToList(measurementUnitDOS, MeasurementUnitDTO.class);
        }else {
            return null;
        }
    }

    @Override
    public List<MeasurementUnitDTO> queryMeasurementUnitByCode(RepeatMeasurementUnitDTO repeatMeasurementUnitDTO) {
        //封装查询条件QueryWrapper对象
        QueryWrapper<MeasurementUnitDO> wrapper = new QueryWrapper<>();
        //设置查询条件
        wrapper.eq("code", repeatMeasurementUnitDTO.getMeasurementUnitDTO().getCode());
        //如果是更新 则去重
        if(repeatMeasurementUnitDTO.getIsUpdate()){
            wrapper.ne("id", repeatMeasurementUnitDTO.getMeasurementUnitDTO().getId());
        }
        List<MeasurementUnitDO> measurementUnitDOS = measurementUnitDAO.selectList(wrapper);
        if(measurementUnitDOS != null && measurementUnitDOS.size() > 0){
            return BeanUtils.copyToList(measurementUnitDOS, MeasurementUnitDTO.class);
        }else {
            return null;
        }
    }

    /**
     * 通过计量单位名称获取计量单位id
     * @param unitName
     * @return
     */
    @Override
    public List<Long> getIdByUnitName(String unitName) {
        return measurementUnitDAO.findUnitIdByName(unitName);
    }

    @Override
    public MeasurementUnitVO saveMeasurementUnit(MeasurementUnitVO measurementUnitVO) throws ServiceException {
        //获取当前用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        //封装DTO对象
        MeasurementUnitDTO measurementUnitDTO = BeanUtils.copyToObject(measurementUnitVO, MeasurementUnitDTO.class);
        measurementUnitDTO.setStatus(GenericStatusEnum.NORMAL.getValue());
        CurrentUserUtils.setCreateDefaultField(measurementUnitDTO, currentUserDTO);
        //新建查重对象
        RepeatMeasurementUnitDTO repeatMeasurementUnitDTO = new RepeatMeasurementUnitDTO();
        repeatMeasurementUnitDTO.setMeasurementUnitDTO(measurementUnitDTO);
        repeatMeasurementUnitDTO.setIsUpdate(false);
        //如果名称重复 抛出异常
        List<MeasurementUnitDTO> measurementUnitDTOSName = this.queryMeasurementUnitByName(repeatMeasurementUnitDTO);
        if(measurementUnitDTOSName != null && !measurementUnitDTOSName.isEmpty()){
            throw new ServiceException(MeasurementUnitErrorCodeEnum.NAME_REPEAT.getErrorCode(), MeasurementUnitErrorCodeEnum.NAME_REPEAT.getErrorMessage());
        }
        //如果编号重复 抛出异常
        List<MeasurementUnitDTO> measurementUnitDTOSCode = this.queryMeasurementUnitByCode(repeatMeasurementUnitDTO);
        if(measurementUnitDTOSCode != null && !measurementUnitDTOSCode.isEmpty()){
            throw new ServiceException(MeasurementUnitErrorCodeEnum.CODE_REPEAT.getErrorCode(), MeasurementUnitErrorCodeEnum.CODE_REPEAT.getErrorMessage());
        }
        //保存计量单位
        MeasurementUnitDTO resultDTO = this.save(measurementUnitDTO);
        //将计量单位DTO对象转化为VO对象，并返回
        return  BeanUtils.copyToObject(resultDTO, MeasurementUnitVO.class);
    }

    @Override
    public MeasurementUnitVO detailMeasurementUnit(Long measurementUnitId) throws ServiceException {
        //通过计量单位id获取计量单位DTO对象
        MeasurementUnitDTO measurementUnitDTO = this.getById(measurementUnitId);
        if(measurementUnitDTO == null){
            return null;
        }else {
            //封装计量单位信息VO对象，并返回
            return BeanUtils.copyToObject(measurementUnitDTO, MeasurementUnitVO.class);
        }
    }

    @Override
    public void updateMeasurementUnit(MeasurementUnitVO measurementUnitVO) throws ServiceException {
        Long measurementUnitVOId = measurementUnitVO.getId();
        if (measurementUnitVOId == null){
            throw new ServiceException(MeasurementUnitErrorCodeEnum.PARAM_MEASUREMENTUNIT_ID_IS_NULL.getErrorCode(), MeasurementUnitErrorCodeEnum.PARAM_MEASUREMENTUNIT_ID_IS_NULL.getErrorMessage());
        }
        //通过计量单位id获取计量单位DTO对象
        MeasurementUnitDTO measurementUnitDTO = this.getById(measurementUnitVOId);
        if(measurementUnitDTO == null){
            throw new ServiceException(MeasurementUnitErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorCode(), MeasurementUnitErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorMessage());
        }
        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        //封装待修改的计量单位DTO对象
        BeanUtils.copyObject(measurementUnitVO, measurementUnitDTO);
        CurrentUserUtils.setUpdateDefaultField(measurementUnitDTO, currentUserDTO);
        //新建查重对象
        RepeatMeasurementUnitDTO repeatMeasurementUnitDTO = new RepeatMeasurementUnitDTO();
        repeatMeasurementUnitDTO.setMeasurementUnitDTO(measurementUnitDTO);
        repeatMeasurementUnitDTO.setIsUpdate(true);
        //如果已存在名称重复 抛出异常
        List<MeasurementUnitDTO> measurementUnitDTOSName = this.queryMeasurementUnitByName(repeatMeasurementUnitDTO);
        if(measurementUnitDTOSName != null && !measurementUnitDTOSName.isEmpty()){
            throw new ServiceException(MeasurementUnitErrorCodeEnum.NAME_REPEAT.getErrorCode(), MeasurementUnitErrorCodeEnum.NAME_REPEAT.getErrorMessage());
        }
        //如果已存在编号重复 抛出异常
        List<MeasurementUnitDTO> measurementUnitDTOSCode = this.queryMeasurementUnitByCode(repeatMeasurementUnitDTO);
        if(measurementUnitDTOSCode != null && !measurementUnitDTOSCode.isEmpty()){
            throw new ServiceException(MeasurementUnitErrorCodeEnum.CODE_REPEAT.getErrorCode(), MeasurementUnitErrorCodeEnum.CODE_REPEAT.getErrorMessage());
        }
        //修改操作
        this.update(measurementUnitDTO);
    }

    @Override
    public void deleteMeasurementUnit(Long measurementUnitId) throws ServiceException {
        //通过计量单位id获取计量单位DTO对象
        MeasurementUnitDTO measurementUnitDTO = this.getById(measurementUnitId);
        if(measurementUnitDTO == null){
            throw new ServiceException(MeasurementUnitErrorCodeEnum.PARAM_NOT_FIND.getErrorCode(), MeasurementUnitErrorCodeEnum.PARAM_NOT_FIND.getErrorMessage());
        }
        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        //封装待修改的计量单位DTO对象
        measurementUnitDTO.setStatus(GenericStatusEnum.DELETED.getValue());
        CurrentUserUtils.setUpdateDefaultField(measurementUnitDTO, currentUserDTO);
        //修改操作
        this.update(measurementUnitDTO);
    }

    @Override
    public void disableMeasurementUnit(Long measurementUnitId) throws ServiceException {
        //通过计量单位id获取计量单位DTO对象
        MeasurementUnitDTO measurementUnitDTO = this.getById(measurementUnitId);
        if (measurementUnitDTO == null) {
            throw new ServiceException(MeasurementUnitErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorCode(), MeasurementUnitErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorMessage());
        }

        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        //封装待修改的计量单位DTO对象
        measurementUnitDTO.setStatus(GenericStatusEnum.DISABLE.getValue());
        CurrentUserUtils.setUpdateDefaultField(measurementUnitDTO, currentUserDTO);

        //修改操作
        this.update(measurementUnitDTO);
    }

    @Override
    public void enableMeasurementUnit(Long measurementUnitId) throws ServiceException {
        ///通过计量单位id获取计量单位DTO对象
        MeasurementUnitDTO measurementUnitDTO = this.getById(measurementUnitId);
        if (measurementUnitDTO == null) {
            throw new ServiceException(MeasurementUnitErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorCode(), MeasurementUnitErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorMessage());
        }

        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        //封装待修改的计量单位DTO对象
        measurementUnitDTO.setStatus(GenericStatusEnum.NORMAL.getValue());
        CurrentUserUtils.setUpdateDefaultField(measurementUnitDTO, currentUserDTO);

        //修改操作
        this.update(measurementUnitDTO);
    }

    /**
     * 批量保存计量单位信息
     *
     * @param measurementUnitDTOList 计量单位信息
     * @return {@link Boolean}
     */
    @Override
    public Boolean saveBatch(List<MeasurementUnitDTO> measurementUnitDTOList) {
        if (CollUtil.isNotEmpty(measurementUnitDTOList)) {
            List<MeasurementUnitDO> toSaveList = BeanUtils.copyToList(measurementUnitDTOList, MeasurementUnitDO.class);
            return SqlHelper.retBool(measurementUnitDAO.insertBatch(toSaveList));
        }
        return Boolean.TRUE;
    }
}
